package org.tools.encrypt;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

import org.apache.commons.codec.binary.Base64;
import org.tools.file.FileUtil;

/** 
 * 加密算法。 <br>
 * 1.MD5 <br>
 * 2.SHA-256 <br>
 * 3.对称加解密算法
 *
 * <pre> 
 * 构建组：e-tools
 * 作者：eddy
 * 邮箱：1546077710@qq.com
 * 日期：2017年4月23日-下午6:31:38
 * 版权：E源时代
 * </pre>
 */
public class EncryptUtil {

	/**
	 * 使用MD5加密 字符串
	 * 
	 * @param inStr
	 * @return
	 * @throws Exception
	 */
	public static String encryptMd5(String inStr) throws Exception {
		return encryptMd5(inStr.getBytes());
	}

	/**
	 * 对String进行md5加密
	 *
	 * @param bytes
	 * @return
	 * @throws Exception
	 */
	private static String encryptMd5(byte[] bytes) throws Exception {
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance("MD5");
			byte[] digest = md.digest(bytes);
			return new String(Base64.encodeBase64(digest));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 使用MD5加密 指定文件路径<br>
	 * String fileName = "e:\\ibps1.sql";<br>
	 * String str = encryptFileMd5(fileName);
	 * 
	 * @param fileName
	 * @return
	 * @throws Exception
	 */
	public static String encryptFileMd5(String fileName) throws Exception {
		byte[] bytes = FileUtil.readByte(fileName);
		return encryptMd5(bytes);
	}

	/**
	 * 输出明文按sha-256加密后的密文
	 * 
	 * @param inputStr
	 *            明文
	 * @return
	 */
	public static synchronized String encryptSha256(String inputStr) {
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-256");
			byte digest[] = md.digest(inputStr.getBytes("UTF-8"));
			return new String(Base64.encodeBase64(digest));
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 *
	 *
	 * @param b
	 * @return
	 */
	public static String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";

		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1) {
				hs = hs + "0" + stmp;
			} else {
				hs = hs + stmp;
			}
			// if(16==hs.length()) break;
		}
		return hs.toLowerCase();
	}

	/**
	 * 密钥
	 */
	private static final String DEFAULT_KEY = "@#$%^6a7";

	/**
	 * 
	 * 对称解密算法
	 *
	 * @param message
	 * @param key
	 *            解密Key
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(String message, String key) throws Exception {
		byte[] bytesrc = stringToBytes(message);
		Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
		DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));

		cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);

		byte[] retByte = cipher.doFinal(bytesrc);
		return new String(retByte, "UTF-8");
	}

	/**
	 * 对称解密算法(默认key)
	 * 
	 * @param message
	 *            解密字符串
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(String message) throws Exception {
		return decrypt(message, DEFAULT_KEY);
	}

	/**
	 * 
	 * 对称加密算法
	 *
	 * @param message
	 *            加密字符串
	 * @param key
	 *            加密key
	 * @return
	 * @throws Exception
	 */
	public static String encrypt(String message, String key) throws Exception {
		Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

		DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));

		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
		cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

		return bytesToString(cipher.doFinal(message.getBytes("UTF-8")));
	}

	/**
	 * 对称加密算法(默认key)
	 * 
	 * @param message
	 * @return
	 * @throws Exception
	 */
	public static String encrypt(String message) throws Exception {
		return encrypt(message, DEFAULT_KEY);
	}

	/**
	 * String转Byte数组
	 * 
	 * @param temp
	 * @return
	 */
	public static byte[] stringToBytes(String temp) {
		byte digest[] = new byte[temp.length() / 2];
		for (int i = 0; i < digest.length; i++) {
			String byteString = temp.substring(2 * i, 2 * i + 2);
			int byteValue = Integer.parseInt(byteString, 16);
			digest[i] = (byte) byteValue;
		}
		return digest;
	}

	/**
	 * Byte数组转String
	 * 
	 * @param b
	 * @return
	 */
	public static String bytesToString(byte b[]) {
		StringBuffer hexString = new StringBuffer();
		for (int i = 0; i < b.length; i++) {
			String plainText = Integer.toHexString(0xff & b[i]);
			if (plainText.length() < 2)
				plainText = "0" + plainText;
			hexString.append(plainText);
		}
		return hexString.toString();
	}

}
